/* 
 * Copyright (c) 2022, CENTRIN.CIYUN.LTD. All rights reserved.
 */
package com.cory.boot.base;

import java.util.Collection;
import java.util.List;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.beust.jcommander.internal.Lists;
import com.cory.boot.component.cache.RedisUtils;
import com.cory.boot.domain.enumdef.EState;
import com.cory.utils.bean.ReflectioUtils;

/**
 * @author xiongcong
 * @date 2022-01-10
 */
public class BaseService<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> {
    
    static final int EXPIRETIME = 15 * 60;
    
    @SuppressWarnings("unchecked")
    public T getByCache(Integer id) {
        Class<?> clazz = ReflectioUtils.getClassGenricType(this.getClass(), 1);
        String key = BaseConstants.CACHE_PREFIX + ":" + clazz.getName() + ":" + id;
        
        Object cache = RedisUtils.getObj(key, clazz);
        if (cache != null) {
            return (T)cache;
        }
        T t = super.getById(id);
        if (t != null) {
            RedisUtils.setObj(key, t, EXPIRETIME);
        }
        
        return t;
    }
    
    @SuppressWarnings({"rawtypes", "unchecked"})
    public List<T> getByIds(List<Integer> ids) {
        Collection collection = super.listByIds(ids);
        return Lists.newArrayList(collection);
    }
    
    public boolean delete(Integer id) {
        return this.updateState(id, EState.DELETE.key);
    }
    
    public boolean enable(Integer id) {
        return this.updateState(id, EState.ENABLE.key);
    }
    
    public boolean disable(Integer id) {
        return this.updateState(id, EState.DISABLE.key);
    }
    
    @SuppressWarnings("unchecked")
    public boolean updateState(Integer id, Integer state) {
        try {
            Class<?> clazz = ReflectioUtils.getClassGenricType(this.getClass(), 1);
            
            Object obj = clazz.newInstance();
            ReflectioUtils.setFieldValue(obj, "id", id);
            ReflectioUtils.setFieldValue(obj, "state", state);
            return super.updateById((T)obj);
        } catch(Exception e) {
            throw ReflectioUtils.convertExceptionToUnchecked(e);
        }
    }
    
    public boolean deleteByIds(List<Integer> ids) {
        return this.updateStateByIds(ids, EState.DELETE.key);
    }
    
    public boolean enableByIds(List<Integer> ids) {
        return this.updateStateByIds(ids, EState.ENABLE.key);
    }
    
    public boolean disableByIds(List<Integer> ids) {
        return this.updateStateByIds(ids, EState.DISABLE.key);
    }
    
    @SuppressWarnings("unchecked")
    public boolean updateStateByIds(List<Integer> ids, Integer state) {
        if (ids == null || ids.size() == 0) {
            return false;
        }
        
        try {
            Class<?> clazz = ReflectioUtils.getClassGenricType(this.getClass(), 1);
            
            Object obj = clazz.newInstance();
            ReflectioUtils.setFieldValue(obj, "state", state);
            
            UpdateWrapper<T> wrapper = new UpdateWrapper<>();
            wrapper.in("id", ids);
            return super.update((T)obj, wrapper);
        } catch(Exception e) {
            throw ReflectioUtils.convertExceptionToUnchecked(e);
        }
    }
}
